package com.nuyoah.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.nuyoah.common.dto.UserDto;
import com.nuyoah.entity.Menu;
import com.nuyoah.entity.Registration;
import com.nuyoah.entity.Role;
import com.nuyoah.entity.User;
import com.nuyoah.mapper.UserMapper;
import com.nuyoah.service.MenuService;
import com.nuyoah.service.RoleService;
import com.nuyoah.service.UserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.nuyoah.utils.RedisUtil;
import lombok.val;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author xiaoming
 * @since 2024-03-26
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {


    @Autowired
    RoleService roleService;

    @Autowired
    UserMapper userMapper;

    @Autowired
    MenuService menuService;

    @Autowired
    RedisUtil redisUtil;

    @Override
    public User getByUsername(String username) {
        return getOne(new QueryWrapper<User>().eq("username", username));
    }

    @Override
    public String getUserAuthorityInfo(Long userId) {

        User user = userMapper.selectById(userId);

        //  ROLE_admin,ROLE_normal,sys:user:list,....
        String authority = "";

        if (redisUtil.hasKey("GrantedAuthority:" + user.getUsername())) {
            authority = (String) redisUtil.get("GrantedAuthority:" + user.getUsername());
        } else {
            //获取角色编码
            List<Role> roles = roleService.list(new QueryWrapper<Role>()
                    .inSql("id", "select role_id from user_role where user_id =" + userId));

            if (roles.size() > 0) {
                String roleCodes = roles.stream().map(r -> "ROLE_" + r.getCode()).collect(Collectors.joining(","));
                authority = roleCodes.concat(",");
            }

            //获取菜单编码
            List<Long> menuIds = userMapper.getNavMenuIds(userId);
            if (menuIds.size() > 0) {
                List<Menu> menus = menuService.listByIds(menuIds);
                String menuPerms = menus.stream().map(m -> m.getPerms()).collect(Collectors.joining(","));
                authority = authority.concat(menuPerms);
            }

            redisUtil.set("GrantedAuthority:" + user.getUsername(), authority, 60 * 60);
        }
        return authority;
    }

    @Override
    public void clearUserAuthorityInfo(String username) {
        redisUtil.del("GrantedAuthority:" + username);
    }

    @Override
    public void clearUserAuthorityInfoByRoleId(Long roleId) {
        List<User> users = this.list(new QueryWrapper<User>().inSql("id","select user_id from user_role where role_id =" + roleId));
        users.forEach(u-> {
            this.clearUserAuthorityInfo(u.getUsername());
        });


    }

    @Override
    public void clearUserAuthorityInfoByMenuId(Long menuId) {
        List<User> users = userMapper.listByMenuId(menuId);
        users.forEach(u-> {
            this.clearUserAuthorityInfo(u.getUsername());
        });
    }

    @Override
    public User getByUsernameOrStudentId(String usernameOrStudentId) {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("username", usernameOrStudentId).or().eq("student_id", usernameOrStudentId);
        return userMapper.selectOne(queryWrapper);
    }

    @Override
    public List<UserDto> getUserDto(List<Registration> registrations) {
        return registrations.stream().map(r -> {
            User user = userMapper.selectById(r.getUserId());
            UserDto userDto = new UserDto();
            userDto.setId(user.getId());
            userDto.setUsername(user.getUsername());
            userDto.setStudentId(user.getStudentId());
            userDto.setName(user.getName());
            userDto.setTime(r.getTime());
            return userDto;
        }).collect(Collectors.toList());
        }
}
